package com.ls.pattern.interpreter.calculator;

import com.ls.pattern.interpreter.IArithmeticInterpreter;
import com.ls.pattern.interpreter.NumInterpreter;
import com.ls.pattern.interpreter.constants.SymbolEnum;
import com.ls.pattern.interpreter.util.OperateUtils;

import java.util.Stack;

/**
 * 解释器模式计算类
 *
 * @author 挥之以墨
 */
public class Calculator {

    private Stack<IArithmeticInterpreter> interpreterStack = new Stack<>();
    private Stack<String> symbolStack = new Stack<>();

    public Calculator(String expresion) {
        this.parse(expresion);
    }

    private void parse(String expresion) {
        String[] elements = expresion.split("\\s");
        for (String element : elements) {
            if (OperateUtils.isSymbol(element)) {
                // 判断运算符优先级，如果当前符号优先级低于栈顶符号，则先将栈顶位置的符号和数字计算出来
                while (!OperateUtils.comparePri(element, symbolStack)) {
                    this.calculate();
                }
                symbolStack.push(element);
                // 去括号
                if (SymbolEnum.RIGHT_BRACKET.getSymbol().equals(element)) {
                    symbolStack.pop();
                    symbolStack.pop();
                }
            } else {
                interpreterStack.push(new NumInterpreter(element));
            }
        }

        // 符号栈不为空时，继续做计算
        while (!symbolStack.empty()){
            calculate();
        }
    }

    private void calculate() {
        IArithmeticInterpreter right = interpreterStack.pop();
        IArithmeticInterpreter left = interpreterStack.pop();
        String symbol = symbolStack.pop();
        interpreterStack.push(OperateUtils.getInterpreter(left, right, symbol));
    }

    public int getResult() {
        return interpreterStack.pop().interpret();
    }

}
